package com.cskaoyan.javase.oop1._9exercise;

/**
 * 读程序题,分析程序的输出,分析程序的执行流程
 * 从程序中的main方法开始看
 * 但是要注意: 启动main方法,要先类加载这个启动类
 *
 * 创建某个类的对象 首先要考虑类加载
 * 创建对象中,代码的执行,要从new对象的构造器方法栈帧进栈开始
 *
 * @since 11:01
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        Student s = new Student(18, "长风");
        System.out.println(s.age);
        System.out.println(s.name);
        System.out.println(s.var);
        System.out.println(s.cat.price);
    }
}

class Student {
    int age = 10;
    String name = "张三";
    double var = 20;

    public Student(int age) {
        System.out.println("Student age");
        this.age = age;
    }

    public Student() {
    }

    public Student(int age, String name) {
        this(age);
        System.out.println("Student age,name");
        this.name = name;
    }

    /*
        引用数据类型成员变量的显式赋值
        和
        int a = 10;
        没有本质区别

        但是引用数据类型的显式赋值new对象
        需要创建Cat对象

        于是首先类加载Cat类
        类加载完毕后,new 创建Cat对象
        执行Cat类的单参price构造器
        于是整个程序的第一行输出就有了: "Cat price"

        以上过程全部都是为了执行Student类对象中成员变量的显式赋值
        该行执行结束后,显式赋值结束,开始执行构造器代码
     */
    Cat cat = new Cat(1000);
    // 没有显式赋值,只有默认值,不会执行该行
    Cat c2;
    /*
        在自身类成员变量中创建自身类的对象
        这样会导致什么结果?
        会导致一直调用自身类的构造器
        方法栈帧一直进栈 不会出栈
        所以就是递归 就会导致栈溢出错误~
     */
    // Student s = new Student();
}

class Cat {
    double price;

    public Cat() {
    }

    public Cat(double price) {
        System.out.println("Cat price");
        this.price = price;
    }
}